import 'package:sqflite/sqflite.dart';

import 'package:path/path.dart';
import 'package:flutter_uxin/Tools/config/commonTool.dart';
import 'package:flutter_uxin/addressBook/Parsers/commonAddressBook.dart';

class DBManager {
  String BDPath;
  Database _database;

//  setDatabase() async {
//    BDPath = await setChatsDatabasePath();
//    print('BDPath------------$BDPath');
//    createDatabase(BDPath);
//  }

  // 单例公开访问点
  factory DBManager() => shared();

  // 静态私有成员，没有初始化
  static DBManager _instance;

  // 私有构造函数
  DBManager._() {
    // 具体初始化代码
//
//    new Future(
//        setBDPath()
//     ).then(setDatabase()); // 明确表现出了后者依赖前者设置的变量值

//    Future<Null> future = new Future(() => null);
//    future.then((_){
//      setBDPath();
//      print("then");
//    }).then((_){
//      setDatabase();
//      print("whenComplete");
//    }).catchError((_){
//      print("catchError");
//    });

//    Future<Null> future = new Future(() => null);
//    future.then(
//      setBDPath();
//      print("then");
//    ).then((_){
//      setDatabase();
//      print("whenComplete");
//    }).catchError((_){
//      print("catchError");
//    });

//    setDatabase();
  }

  // 静态、同步、私有访问点
  static DBManager shared() {
    if (_instance == null) {
      _instance = DBManager._();
    }
    return _instance;
  }

  Future<Database> get database async {
    if (_database != null) {
      return _database;
    }
    _database = await initDb();

    return _database;
  }

  initDb() async {
    String path = await setChatsDatabasePath();
    BDPath = path;
    var db = await openDatabase(path, version: 1, onCreate: _onCreate);
    return db;
  }

  Future<String> setChatsDatabasePath() async {
    String user_name = await commonTool.getPreferencesValue('profile_name');
//    print('user_name------------$user_name');

    String databasesPath = await getDatabasesPath();
    if (databasesPath is String &&
        databasesPath.isNotEmpty == true &&
        user_name is String &&
        user_name.isNotEmpty == true) {
      String path = join(databasesPath, user_name, 'chatsDatabase.db');
      print('path------------$path');
      return path;
    }
    return '';
  }

//创建数据库表
  void _onCreate(Database db, int version) async {
    print('创建数据库表');
    await db.execute(
        "CREATE TABLE Groups_Table(GroupID TEXT PRIMARY KEY, setName TEXT, membersCount TEXT, name TEXT, classId TEXT, createdAt TEXT, teacherInCharge TEXT, gradeId TEXT, schoolId TEXT, yjtGroupId TEXT, creatorId TEXT, save TEXT, groupType TEXT)");
    await db.execute(
        "CREATE TABLE Users_Table(UserID TEXT PRIMARY KEY, save TEXT, name TEXT,mobile TEXT,pinyin TEXT,quanpin TEXT,userType INTEGER NOT NULL  DEFAULT 0,schoolId TEXT,flagOfUpdating INTEGER,post TEXT,realName TEXT,headerImageUrl TEXT)");
    await db.execute(
        "CREATE TABLE Groups_Users_Table(GroupID   TEXT NOT NULL,UserID    TEXT NOT NULL, userName    TEXT NOT NULL, namePrefix     TEXT NOT NULL,headImageUrl   TEXT ,realName    TEXT ,UserType    INTEGER NOT NULL  DEFAULT 0,PRIMARY KEY (GroupID,UserID))");
  }

//创建数据库表
  void _onOpen(Database db) async {
    print('创建数据库表');
    await db.execute(
        "CREATE TABLE IF NOT EXISTS Groups_Table(GroupID TEXT PRIMARY KEY, setName TEXT, membersCount TEXT, name TEXT, classId TEXT, createdAt TEXT, teacherInCharge TEXT, gradeId TEXT, schoolId TEXT, yjtGroupId TEXT, creatorId TEXT, save TEXT, groupType TEXT)");
    await db.execute(
        "CREATE TABLE IF NOT EXISTS Users_Table(UserID TEXT PRIMARY KEY, save TEXT, name TEXT,mobile TEXT,pinyin TEXT,quanpin TEXT,userType INTEGER NOT NULL  DEFAULT 0,schoolId TEXT,flagOfUpdating INTEGER,post TEXT,realName TEXT,headerImageUrl TEXT)");
    await db.execute(
        "CREATE TABLE IF NOT EXISTS Groups_Users_Table(GroupID   TEXT NOT NULL,UserID    TEXT NOT NULL, userName    TEXT NOT NULL, namePrefix     TEXT NOT NULL,headImageUrl   TEXT ,realName    TEXT ,UserType    INTEGER NOT NULL  DEFAULT 0,PRIMARY KEY (GroupID,UserID))");
  }

  deleteAllAddressTable() async {
    var dbClient = await database;
    var count_Groups = -1;
    var count_Users = -1;
    var count_Groups_Users = -1;

    count_Groups = await dbClient.delete('Groups_Table');
    count_Users = await dbClient.delete('Users_Table');
    count_Groups_Users = await dbClient.delete('Groups_Users_Table');

//    print('count_Groups---------------$count_Groups');
//    print('count_Users---------------$count_Users');
//    print('count_Groups_Users---------------$count_Groups_Users');

    if (count_Groups >= 0 && count_Users >= 0 && count_Groups_Users >= 0) {
      return true;
    } else {
      return false;
    }
  }

  insertGroupsList(List<Groups> groupsList) async {
    groupsList.forEach((groups) {
      insertGroup(groups);
    });
  }

  insertGroup(Groups groups) async {
    var dbClient = await database;

    await dbClient.transaction((txn) async {
      int id1 = await txn.rawInsert(
//            'INSERT INTO Groups_Table(id , setName , membersCount , name , classId , createdAt , teacherInCharge , gradeId , schoolId , yjtGroupId , creatorId , save , groupType )'
//                ' VALUES(groups.id}, groups.setName}, groups.membersCount}, groups.name}, groups.classId}, groups.createdAt}, groups.teacherInCharge}, groups.gradeId}, groups.schoolId}, groups.yjtGroupId}, groups.creatorId}, groups.save}, groups.groupType})');
          'INSERT OR REPLACE INTO Groups_Table(GroupID , setName , membersCount , name , classId , createdAt , teacherInCharge , gradeId , schoolId , yjtGroupId , creatorId , save , groupType )'
          ' VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
          [
            groups.id,
            groups.setName,
            groups.membersCount,
            groups.name,
            groups.classId,
            groups.createdAt,
            groups.teacherInCharge,
            groups.gradeId,
            groups.schoolId,
            groups.yjtGroupId,
            groups.creatorId,
            groups.save,
            groups.groupType
          ]);

//      print('inserted1: $id1');

      insertUsersList(groups.members);

      insertGroupUserList(groups, groups.members);
    });
  }

  insertUsersList(List<Members> usersList) async {
    usersList.forEach((members) {
      insertMember(members);
    });
  }

  insertMember(Members members) async {
    var dbClient = await database;
    await dbClient.transaction((txn) async {
      int id1 = await txn.rawInsert(
//            'INSERT INTO Users_Table(UserID , save , name ,mobile ,pinyin ,quanpin ,userType ,schoolId ,flagOfUpdating ,post ,realName ,headerImageUrl ) '
//                'VALUES(members.id}, members.save},members.name},members.mobile},members.pinyin},members.quanpin},members.userType},members.schoolId},members.flagOfUpdating},members.post},members.realName},members.headerImageUrl},)');
          'INSERT OR REPLACE INTO Users_Table(UserID , save , name ,mobile ,pinyin ,quanpin ,userType ,schoolId ,flagOfUpdating ,post ,realName ,headerImageUrl ) '
          'VALUES(?,?,?,?,?   ,?,?,?,?,?   ,?,?)',
          [
            members.id,
            members.save,
            members.name,
            members.mobile,
            members.pinyin,
            members.quanpin,
            members.userType,
            members.schoolId,
            members.flagOfUpdating,
            members.post,
            members.realName,
            members.headerImageUrl
          ]);

//      print('inserted1: $id1');
    });
  }

  insertGroupUserList(Groups groups, List<Members> usersList) async {
    usersList.forEach((members) {
      insertGroupUser(groups: groups, members: members);
    });
  }

  insertGroupUser({Groups groups, Members members}) async {
    var dbClient = await database;

    await dbClient.transaction((txn) async {
      int id1 = await txn.rawInsert(
          'INSERT OR REPLACE INTO Groups_Users_Table(GroupID  ,UserID   , userName   , namePrefix    ,headImageUrl    ,realName     ,UserType  ) '
          'VALUES(?,?,?,?,?  ,?,?)',
          [
            groups.id,
            members.id,
            members.name,
            members.pinyin,
            members.headerImageUrl,
            members.realName,
            members.userType
          ]);
//      print('inserted1: $id1');
    });
  }

  getGroupsWithOutGroupTypeList(String  groupTypeList) async{
    List <Groups> groupsList = new List();
    List<Map> list;
    var dbClient = await database;

    await dbClient.transaction((txn) async {
        list =
//      await txn.rawQuery('SELECT * FROM Groups_Table WHERE save = 1 AND groupType NOT IN (?)', [groupTypeList]);
      await txn.rawQuery('SELECT * FROM Groups_Table ',);

      print('list-------$list');

    });

    await Future.forEach(list, (map) async {
      Groups  groups =  Groups.fromDBJson(map);
      List <Members> membersList = await getUsersByGroupId(groups.id);
//      print('groups.id-------${groups.id}');
//      print('membersList-------$membersList');
      groups.members =  membersList;
      groupsList.add(groups);

    });


//    print('members-------${groupsList.first.members}');
    return groupsList;


  }


  getUsersByGroupId(String groupId) async {
    List <Members> membersList = new List();

    var dbClient = await database;

    await dbClient.transaction((txn) async {
      List<Map> list =
          await txn.rawQuery('SELECT * FROM Users_Table WHERE UserID IN (SELECT DISTINCT UserID FROM Groups_Users_Table WHERE GroupID =?)', [groupId]);
//      await txn.rawQuery('SELECT * FROM Groups_Users_Table WHERE GroupID =?', [groupId]);
      list.forEach((map){
          Members  members =  Members.fromDBJson(map);
          membersList.add(members);
//      print('map---------$map');
      });


    });

    return membersList;


  }
}
